﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UpdateUDMBackService
{
    public class CommonUtil
    {
        private static string _isInDomain = null;
        private static string ExeName = "UDMBackService.exe";
        private static string _loginUserName = "";
        public static string GetAppPath()
        {
            string codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
            string filePath = Path.GetDirectoryName(codeBase) + "\\";
            filePath = filePath.Substring(6);
            return filePath;
        }
        /// <summary>
        /// 判断本机是否在域里，如果在域里返回域名
        /// </summary>
        /// <returns></returns>
        public static bool IsInDomain(ref string domainName, ref string userName)
        {
            try
            {
                Domain domain = Domain.GetCurrentDomain();
                domainName = domain.Name;
                userName = Environment.UserDomainName;
                userName = Environment.UserName;
                return true;
            }
            catch (Exception ex)
            {
                //log.Error("IsInDomain:", ex);
                return false;
            }
        }
        /// <summary>
        /// 判断本机是否在域里
        /// </summary>
        /// <returns></returns>
        public static bool IsInDomain()
        {
            try
            {
                Domain domain = Domain.GetCurrentDomain();
                return true;
            }
            catch (Exception ex)
            {
                //log.Error("IsInDomain:", ex);
                //Console.WriteLine(ex.Message);
                return false;
            }
        }
        private static string FileVer()
        {
            string ver = "";
            string filePath = CommonUtil.GetAppPath() + "UDMBackService.exe";

            try
            {
                // 获取文件版本信息
                FileVersionInfo versionInfo = FileVersionInfo.GetVersionInfo(filePath);
                ver = versionInfo.FileVersion;
                // 输出版本号（例如：1.0.0.0）
                //Console.WriteLine("文件版本: " + versionInfo.FileVersion);
                //Console.WriteLine("产品版本: " + versionInfo.ProductVersion);
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("文件不存在！");
            }
            catch (Exception ex)
            {
                Console.WriteLine("错误: " + ex.Message);
            }
            return ver;
        }
        public static async Task<bool> InitToken()
        {
            CXToken cXToken = await NetworkUtil.GetToken();
            if (cXToken != null)
            {
                NetworkUtil.Token = cXToken.data.access_token;
                //设置定时任务，token失效前更新token
                System.Timers.Timer t = new System.Timers.Timer(cXToken.data.expires_in * 1000 - 900000);//设置时间间隔,失效前15分钟执行
                //System.Timers.Timer t = new System.Timers.Timer(15000);//设置时间间隔,失效前15分钟执行
                t.Elapsed += new System.Timers.ElapsedEventHandler(RefreshToken);//到达时间的时候执行事件
                t.AutoReset = true;//设置是执行一次（false）还是一直执行(true)
                t.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件
            }
            return true;
        }
        /// <summary>
        /// 定时刷新Token
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private static async void RefreshToken(object source, System.Timers.ElapsedEventArgs e)
        {
            CXToken cXToken = await NetworkUtil.GetToken();
            if (cXToken != null)
            {
                NetworkUtil.Token = cXToken.data.access_token;
            }
        }
        //判断是否需要更新本地程序版本
        public static async void UpdateVersion()
        {
            string localVersion = CommonUtil.FileVer();
            string zipFile;
            string[] localArr;
            string[] serverArr;
            //string filePath = @"D:\log1.txt"; // 文件路径
            //StreamWriter writer = new StreamWriter(filePath);
            
            try
            {

                //writer.WriteLine("1");
                if (!CommonUtil.IsInDomain())
                {
                    await CommonUtil.InitToken();
                }
                //writer.WriteLine("2");
                localArr = localVersion.Split('.');
                localVersion = string.Join(".", localArr.Take(localArr.Length - 1));
                //writer.WriteLine("localVersion=" + localVersion);
                //调用接口，看是否需要更新本地版本
                CXResponse<CXVer> cXResponse = await NetworkUtil.GetExcelVerAsync(localVersion);
                if (cXResponse != null && cXResponse.result != null)
                {
                    //writer.WriteLine("3");
                    if (cXResponse.result.data != null &&
                        !string.IsNullOrEmpty(cXResponse.result.data.data.base64))
                    {
                        //writer.WriteLine("4");
                        serverArr = cXResponse.result.data.data.ver.Split('.');
                        if (serverArr.Length < 3)
                        {
                            return;
                        }
                        //判断结果中的版本号与本地是否一致，如果不一致则下载更新本地文件，比较前三位即可
                        //if (localArr[0].Equals(serverArr[0]) &&
                        //    localArr[1].Equals(serverArr[1]) &&
                        //    localArr[2].Equals(serverArr[2]))
                        //writer.WriteLine("serverVer =" + cXResponse.result.data.data.ver);
                        if (!localVersion.Equals(cXResponse.result.data.data.ver))
                        {
                            //writer.WriteLine("5");
                            zipFile = CommonUtil.GetTempPath() + Guid.NewGuid().ToString("N") + ".zip";
                            //把结果中的base64转换成zip文件
                            CommonUtil.ConvertByteArrayToFile(cXResponse.result.data.data.base64, zipFile);
                            KillUDMBackService();
                            //解压覆盖
                            bool vl = ZipUtil.UnZip(zipFile, CommonUtil.GetAppPath());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //writer.WriteLine(ex.Message);
            }
            finally
            {
                //writer.Close();
                //调用常驻内存程序
                Process.Start(CommonUtil.GetAppPath() + ExeName);
                Environment.Exit(0);
            }
        }
        private static void KillUDMBackService()
        {
            // 只查当前用户会话（SessionID == 当前进程所在的会话）
            int mySession = Process.GetCurrentProcess().SessionId;

            var udm = Process.GetProcessesByName("UDMBackService")
                             .FirstOrDefault(p => p.SessionId == mySession);

            if (udm != null)
            {
                Console.WriteLine("发现 UDMBackService.exe，准备关闭…");
                udm.Kill();          // 立即结束
                udm.WaitForExit();   // 可选：等待它完全退出
                Console.WriteLine("已关闭。");
            }
        }
        /// <summary>
        /// 获取临时文件夹目录
        /// </summary>
        /// <returns></returns>
        public static string GetTempPath()
        {
            return System.IO.Path.GetTempPath();
        }
        /// <summary>
        /// 把base64字符串转换成文件
        /// </summary>
        /// <param name="base64"></param>
        /// <param name="filePath"></param>
        public static void ConvertByteArrayToFile(string base64, string filePath)
        {
            byte[] byteArray = Convert.FromBase64String(base64);
            ConvertByteArrayToExcel(byteArray, filePath);
        }
        /// <summary>
        /// 把二进制数组转成文件
        /// </summary>
        /// <param name="byteArray"></param>
        /// <param name="filePath"></param>
        public static void ConvertByteArrayToExcel(byte[] byteArray, string filePath)
        {
            FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);
            fs.Write(byteArray, 0, byteArray.Length);
            fs.Flush();
            fs.Close();
        }
        /// <summary>
        /// 登录系统的用户名
        /// </summary>
        public static string LoginUserName
        {
            get
            {
                if (string.IsNullOrEmpty(_loginUserName))
                {
                    _loginUserName = GetUserName();
                }
                return _loginUserName;
            }
        }
        /// <summary>
        /// 获取电脑的登录账号
        /// </summary>
        /// <returns></returns>
        public static string GetUserName()
        {
            string userName = "";

            try
            {
                //userName = Environment.UserDomainName;
                userName = Environment.UserName;
            }
            catch (Exception ex)
            {
                //log.Error("GetUserName:", ex);
            }
            return userName;
        }
        /// <summary>
        /// 生产指定位随机数字字符串
        /// </summary>
        /// <returns></returns>
        public static string GenerateRandomNumber(int count = 6)
        {
            StringBuilder sb = new StringBuilder();
            Random random = new Random();

            for (int i = 0; i < count; i++)
            {
                int randomNumber = random.Next(10);
                sb.Append(randomNumber);
            }

            return sb.ToString();
        }
        /// <summary>
        /// 本机是否在域里，在域里返回Y，不在返回N
        /// </summary>
        public static string InDomain
        {
            get
            {
                string domainName = "";
                string userName = "";
                if (string.IsNullOrEmpty(_isInDomain))
                {
                    if (CommonUtil.IsInDomain(ref domainName, ref userName))
                    {
                        if (domainName.Equals(ConstUtil.DomainName))
                        {
                            _isInDomain = "Y";
                        }
                        else
                        {
                            _isInDomain = "N";
                        }
                    }
                    else
                    {
                        _isInDomain = "N";
                    }
                }
                return _isInDomain;
            }
        }
    }
}
